package com.cta.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cta.dao.ProfilePersistence;
import com.cta.entity.Contact;
import com.cta.entity.PBX;
import com.cta.entity.PBXFactory;
import com.cta.entity.Profile;
import com.cta.entity.ServiceProvider;
import com.cta.entity.Trunk;
import com.cta.exception.CTAServiceException;
import com.cta.service.ProfileService;
import com.ibm.icu.util.Calendar;

@Service("profileService")
@Transactional(readOnly = true)
public class ProfileServiceImpl implements ProfileService {

	@Autowired
	private ProfilePersistence profilePersistence;

	/**
	 * create provider
	 * 
	 * @param name
	 * @param description
	 */
	@Transactional(readOnly = false)
	public ServiceProvider createServiceProvider(String name, String description) {
		ServiceProvider pr = new ServiceProvider(name, description, Calendar.getInstance().getTime());
		return profilePersistence.save(pr);
	}

	/**
	 * update service provider
	 * 
	 * @param serviceProviderId
	 * @param name
	 * @param description
	 * @return
	 */
	@Transactional(readOnly = false)
	public ServiceProvider updateServiceProvider(Long serviceProviderId, String name, String description) {
		ServiceProvider pr = profilePersistence.findById(ServiceProvider.class, serviceProviderId);
		pr.setName(name);
		pr.setDescription(description);
		return pr;
	}

	/**
	 * check name of service provider
	 * @param name
	 * @return
	 */
	public boolean hasServiceProviderName(String name) {
		ServiceProvider serviceProvider = profilePersistence.findSingleObject(ServiceProvider.class, "name", name);
		return serviceProvider != null ? true : false;
	}
	
	/**
	 * find service provider by id
	 * 
	 * @param pbxServiceProviderId
	 * @return
	 */
	public ServiceProvider findServiceProviderById(Long serviceProviderId) {
		return profilePersistence.findById(ServiceProvider.class, serviceProviderId);
	}

	/**
	 * find all Provider
	 * 
	 * @return
	 */
	public List<ServiceProvider> findAllProviders() {
		return profilePersistence.findAllProviders();
	}

	/**
	 * create trunk
	 * 
	 * @param name
	 * @param description
	 * @return
	 */
	@Transactional(readOnly = false)
	public Trunk createTrunk(String name, String description, Long serviceProviderId, Long pbxId) {
		ServiceProvider serviceProvider = profilePersistence.findById(ServiceProvider.class, serviceProviderId);
		PBX pbx = profilePersistence.findById(PBX.class, pbxId);
		Trunk tr = new Trunk(name, description, Calendar.getInstance().getTime(), serviceProvider, pbx);
		return profilePersistence.save(tr);
	}

	/**
	 * update trunk
	 * 
	 * @param trunkId
	 * @param name
	 * @param description
	 * @param serviceProviderId
	 * @param pbxId
	 * @return
	 */
	@Transactional(readOnly = false)
	public void updateTrunk(Long trunkId, String name, String description, Long serviceProviderId, Long pbxId) {
		Trunk trunk = profilePersistence.findById(Trunk.class, trunkId);
		PBX pbx = profilePersistence.findById(PBX.class, pbxId);
		trunk.setName(name);
		trunk.setDescription(description);
		trunk.setPbx(pbx);
	}

	/**
	 * find all Trunk
	 * 
	 * @return
	 */
	public List<Trunk> findAllTrunks() {
		return profilePersistence.findAllTrunks();
	}

	/**
	 * find list of trunk base on service provider id
	 * 
	 * @param serviceProviderId
	 * @return
	 */
	public List<Trunk> findTrunkByProvider(Long serviceProviderId) {
		return profilePersistence.findTrunkByProvider(serviceProviderId);
	}

	/**
	 * find trunk base on id
	 * 
	 * @param serviceProviderId
	 * @return
	 */
	public Trunk findTrunkById(Long id) {
		Trunk trunk = profilePersistence.findById(Trunk.class, id);
		if (trunk.getServiceProvider() != null) {
			trunk.getServiceProvider().getId();
		}
		if (trunk.getPbx() != null) {
			trunk.getPbx().getId();
		}
		return trunk;
	}

	/**
	 * create pbx factory
	 * 
	 * @param name
	 * @param description
	 * @return
	 */
	@Transactional(readOnly = false)
	public PBXFactory createPBXFactory(String name, String description) {
		PBXFactory pbx = new PBXFactory(name, description, Calendar.getInstance().getTime());
		return profilePersistence.save(pbx);
	}

	/**
	 * update pbx factory
	 * 
	 * @param factoryId
	 * @param name
	 * @param description
	 * @return
	 */
	@Transactional(readOnly = false)
	public PBXFactory editPBXFactory(Long factoryId, String name, String description) {
		PBXFactory pbx = profilePersistence.findById(PBXFactory.class, factoryId);
		if (pbx != null) {
			pbx.setName(name);
			pbx.setDescription(description);
		}
		return pbx;
	}

	/**
	 * check if this name has exist on db
	 * @param name
	 * @return
	 */
	public boolean hasPBXFactoryName(String name) {
		PBXFactory pbxFactory = profilePersistence.findSingleObject(PBXFactory.class, "name", name);
		return pbxFactory != null ? true : false;
	}

	/**
	 * find all pbx factory
	 * 
	 * @return
	 */
	public List<PBXFactory> findAllPBXFactories() {
		return profilePersistence.findAllPBXFactories();
	}

	/**
	 * find pbx factory by id
	 * 
	 * @return
	 */
	public PBXFactory findPBXFactory(Long pbxFactoryId) {
		return profilePersistence.findById(PBXFactory.class, pbxFactoryId);
	}

	/**
	 * find all profile of pbx and eager load pbx
	 * 
	 * @return
	 */
	public List<Profile> findProfileByPBXId(Long pbxId) {
		List<Profile> profiles = profilePersistence.findProfileByPBXId(pbxId);
		return profiles;
	}

	/**
	 * save profile of pbx
	 * 
	 * @param id
	 * @param name
	 * @param description
	 * @param pbxId
	 * @return
	 */
	@Transactional(readOnly = false)
	public void saveProfile(Long[] id, String[] name, String[] description, Integer[] numOfbyte, Integer[] sequences,
			Long pbxId) throws CTAServiceException {
		PBX pbx = profilePersistence.findById(PBX.class, pbxId);
		if (pbx == null) {
			throw new CTAServiceException("PBX not found");
		}
		for (int i = 0; i < name.length; i++) {
			if (id[i] != null && id[i] > 0) {
				Profile p = profilePersistence.findById(Profile.class, id[i]);
				p.setName(name[i]);
				p.setDescription(description[i]);
				p.setNumOfBytes(numOfbyte[i]);
				p.setSequence(sequences[i]);
			} else {
				Profile p = new Profile(sequences[i], name[i], description[i], numOfbyte[i], pbx);
				profilePersistence.save(p);
			}
		}

	}

	/**
	 * delete entity
	 * 
	 * @param profileId
	 */
	@Transactional(readOnly = false)
	public void deleteProfile(Long profileId) {
		profilePersistence.execute("delete from Profile p where p.id = ?1", profileId);
	}
	
	/**
	 * check name of PBX
	 * @param name
	 * @return
	 */
	public boolean hasPBXName(String name) {
		PBX pbx = profilePersistence.findSingleObject(PBX.class, "name", name);
		return pbx != null ? true : false;
	}
	
	/**
	 * check name of Trunk
	 * @param name
	 * @return
	 */
	public boolean hasTrunkName(String name) {
		Trunk trunk = profilePersistence.findSingleObject(Trunk.class, "name", name);
		return trunk != null ? true : false;
	}
	
	/**
	 * check name of user
	 * @param name
	 * @return
	 */
	public boolean hasUserName(String name) {
		Contact user = profilePersistence.findSingleObject(Contact.class, "name", name);
		return user != null ? true : false;
	}
}
